package com.wcy.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.enums.ApiErrorCode;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.wcy.domain.SysMenu;
import com.wcy.feign.JwtToken;
import com.wcy.feign.OAuth2FeignClient;
import com.wcy.model.LoginResult;
import com.wcy.service.SysLoginService;
import com.wcy.service.SysMenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>Title:SysLoginServiceImpl.java</p >
 * <p>Description: </p >
 * <p>Copyright: 公共服务与应急管理战略业务本部 Copyright(c)2020</p >
 * <p>Date:2021/9/19 1:08</p >
 *
 * @author wcy (wangchaoyanga@mail.taiji.com.cn)
 * @version 1.0
 */
@Service
@Slf4j
public class SysLoginServiceImpl implements SysLoginService {

    @Autowired
    private OAuth2FeignClient oAuth2FeignClient;

    @Value("${basic.token:Basic Y29pbi1hcGk6Y29pbi1zZWNyZXQ=}")
    private String basicToken;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private StringRedisTemplate redisTemplate ;

    @Override
    public LoginResult login(String username, String password) {
        log.info("用户{}开始登录", username);
        // 获取token 需要远程调用 authorization-server 服务
        ResponseEntity<JwtToken> tokenResponseEntity = oAuth2FeignClient.getToken("password", username, password, "admin_type", basicToken);
        if (tokenResponseEntity.getStatusCode() != HttpStatus.OK) {
            throw new ApiException(ApiErrorCode.FAILED);
        }
        JwtToken jwtToken = tokenResponseEntity.getBody();
        log.info("远程调用授权服务器成功,获取的token为{}", JSON.toJSONString(jwtToken, true));
        String token = jwtToken.getAccessToken();
        // 查询菜单数据
        Jwt jwt = JwtHelper.decode(token);
        String jwtJson = jwt.getClaims();
        JSONObject jsonObject = JSON.parseObject(jwtJson);
        List<SysMenu> menus = sysMenuService.getMenusByUserId(Long.valueOf(jsonObject.getString("user_name")));
        // 权限数据 不需要查询 因为我们的jwt里面包含权限数据
        JSONArray jsonArray = jsonObject.getJSONArray("authorities");
        List<SimpleGrantedAuthority> authorities =
                jsonArray.stream().map(authorityJson -> new SimpleGrantedAuthority(authorityJson.toString()))
                        .collect(Collectors.toList());
        // 1 将该token 存储在redis 里面，配置我们的网关做jwt验证的操作
        redisTemplate.opsForValue().set(token,"", jwtToken.getExpiresIn() , TimeUnit.SECONDS);
        return new LoginResult(jwtToken.getTokenType()+" "+token, menus, authorities);
    }
}
